package org.szgb.console.sys.department.entity;

import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.format.annotation.DateTimeFormat;
import org.szgb.console.sys.line.entity.SysLine;
import org.szgb.console.utils.PageDto;
import org.szgb.core.base.entity.BeanEntity;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@EqualsAndHashCode(callSuper = true)
@Data
public class SysDepartment extends BeanEntity<SysDepartment> {
    private String name;
    private SysLine sysLine;
    private SysDepartment parent;

    public SysDepartment() {
    }

    public SysDepartment(String id) {
        this.setId(id);
    }

    public SysDepartment(SysDepartment.SysDepartmentFindDto sysDepartmentFindDto) {
        this.setId(sysDepartmentFindDto.getId());
        this.setName(sysDepartmentFindDto.getName());
        this.setSysLine(new SysLine(sysDepartmentFindDto.getLineId()));
        this.setParent(new SysDepartment(sysDepartmentFindDto.getParentId()));
        this.setPageDto(sysDepartmentFindDto.getPageDto());
    }

    public SysDepartment(SysDepartment.SysDepartmentSaveDto sysDepartmentSaveDto) {
        this.setId(sysDepartmentSaveDto.getId());
        this.setName(sysDepartmentSaveDto.getName());
        this.setSysLine(new SysLine(sysDepartmentSaveDto.getLineId()));
        this.setParent(new SysDepartment(sysDepartmentSaveDto.getParentId()));
    }

    public SysDepartment.SysDepartmentView toSysDepartmentView() {
        return new SysDepartment.SysDepartmentView(this);
    }

    @Data
    @Schema(title = "部门信息", description = "部门信息")
    public static class SysDepartmentView {
        @Schema(description = "ID")
        private String id;
        @Schema(description = "名称")
        private String name;
        @Schema(description = "部门归属线路id")
        private String lineId;
        @Schema(description = "部门归属线路名称")
        private String lineName;
        @Schema(description = "父级id")
        private String parentId;
        @Schema(description = "父级名称")
        private String parentName;
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
        @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        @Schema(description = "创建时间")
        private LocalDateTime createdAt;
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
        @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        @Schema(description = "更新时间")
        private LocalDateTime updatedAt;
        @Schema(description = "创建人id")
        private String createdById;
        @Schema(description = "创建人姓名")
        private String createdByName;
        @Schema(description = "更新人id")
        private String updatedById;
        @Schema(description = "更新人姓名")
        private String updatedByName;

        public SysDepartmentView(SysDepartment sysDepartment) {
            this.id = sysDepartment.getId();
            this.name = sysDepartment.getName();
            if (sysDepartment.getSysLine() != null) {
                this.lineId = sysDepartment.getSysLine().getId();
                this.lineName = sysDepartment.getSysLine().getName();
            }
            if (sysDepartment.getParent() != null) {
                this.createdById = sysDepartment.getCreatedBy().getId();
                this.createdByName = sysDepartment.getCreatedBy().getName();
            }
            this.createdAt = sysDepartment.getCreatedAt();
            this.updatedAt = sysDepartment.getUpdatedAt();
            if (sysDepartment.getCreatedBy() != null) {
                this.createdById = sysDepartment.getCreatedBy().getId();
                this.createdByName = sysDepartment.getCreatedBy().getName();
            }
            if (sysDepartment.getUpdatedBy() != null) {
                this.updatedById = sysDepartment.getUpdatedBy().getId();
                this.updatedByName = sysDepartment.getUpdatedBy().getName();
            }
        }

        public static List<SysDepartment.SysDepartmentView> getViewListFromList(List<SysDepartment> sysDepartmentList) {
            return sysDepartmentList.stream().map(SysDepartment.SysDepartmentView::new).toList();
        }
    }

    @Data
    @Schema(title = "部门树表信息", description = "部门树表信息")
    public static class SysDepartmentTreeView {
        @Schema(description = "ID")
        private String id;
        @Schema(description = "名称")
        private String name;
        @Schema(description = "部门归属线路id")
        private String lineId;
        @Schema(description = "部门归属线路名称")
        private String lineName;
        @Schema(description = "子部门")
        private List<SysDepartmentTreeView> children;

        public SysDepartmentTreeView() {
        }

        private SysDepartmentTreeView(SysDepartment sysDepartment) {
            this.id = sysDepartment.getId();
            this.name = sysDepartment.getName();
            if (sysDepartment.getSysLine() != null) {
                this.lineId = sysDepartment.getSysLine().getId();
                this.lineName = sysDepartment.getSysLine().getName();
            }
        }

        public SysDepartmentTreeView(List<SysDepartment> sysDepartmentList) {
            if (sysDepartmentList == null || sysDepartmentList.isEmpty()) {
                this.children = new ArrayList<>();
                return;
            }

            // 所有节点映射：id -> tree node
            Map<String, SysDepartmentTreeView> nodeMap = new HashMap<>();

            // 第一步：为每个部门创建对应的树节点
            for (SysDepartment dept : sysDepartmentList) {
                SysDepartmentTreeView node = new SysDepartmentTreeView();
                node.setId(dept.getId());
                node.setName(dept.getName());
                if (dept.getSysLine() != null) {
                    node.setLineId(dept.getSysLine().getId());
                    node.setLineName(dept.getSysLine().getName());
                }
                node.setChildren(new ArrayList<>());
                nodeMap.put(dept.getId(), node);
            }

            for (SysDepartment dept : sysDepartmentList) {
                String childId = dept.getId();
                SysDepartment parentDept = dept.getParent();

                if (parentDept == null) {
                    // 是根节点
                    this.id = childId;
                    this.name = nodeMap.get(childId).getName();
                    this.children = new ArrayList<>();
                } else {
                    String parentId = parentDept.getId();
                    SysDepartmentTreeView parentNode = nodeMap.get(parentId);
                    if (parentNode != null) {
                        parentNode.getChildren().add(nodeMap.get(childId));
                    }
                    nodeMap.put(parentId, parentNode);
                    // 如果父节点不在列表中，忽略（数据不完整）
                }
            }
            this.children = nodeMap.get(id).getChildren();
        }
    }

    @Data
    @Schema(title = "部门查询表单", description = "部门查询参数")
    public static class SysDepartmentFindDto {
        @Schema(description = "ID")
        private String id;
        @Schema(description = "名称")
        private String name;
        @Schema(description = "部门归属线路id")
        private String lineId;
        @Schema(description = "父级id")
        private String parentId;

        @Schema(description = "分页信息")
        private PageDto pageDto;

        public SysDepartment toSysDepartment() {
            return new SysDepartment(this);
        }
    }

    @Data
    @Schema(title = "部门保存表单", description = "部门保存参数")
    public static class SysDepartmentSaveDto {
        @Schema(description = "id(如为空则为新增数据)")
        private String id;
        @Schema(description = "名称")
        private String name;
        @Schema(description = "部门归属线路id")
        private String lineId;
        @Schema(description = "父级id")
        private String parentId;

        public SysDepartment toSysDepartment() {
            return new SysDepartment(this);
        }
    }
}
